import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:intl/intl.dart';
import 'db_helper.dart';
import 'dart:math' show max;
import 'dart:math' show pow;

class StatisticsPage extends StatefulWidget {
  const StatisticsPage({super.key});

  @override
  State<StatisticsPage> createState() => _StatisticsPageState();
}

class _StatisticsPageState extends State<StatisticsPage> {
  String _selectedPeriod = '月';
  DateTime _selectedDate = DateTime.now();
  List<Map<String, dynamic>> _transactions = [];
  final DateFormat _dateFormat = DateFormat('yyyy-MM-dd');
  final DateFormat _monthFormat = DateFormat('yyyy年MM月');
  final DateFormat _yearFormat = DateFormat('yyyy年');

  @override
  void initState() {
    super.initState();
    _loadTransactions();
  }

  Future<void> _loadTransactions() async {
    final transactions = await DBHelper.getTransactions();
    setState(() {
      _transactions = transactions;
    });
  }

  Future<void> _selectDate() async {
    final DateTime? picked = await showDatePicker(
      context: context,
      initialDate: _selectedDate,
      firstDate: DateTime(2000),
      lastDate: DateTime.now(),
      locale: const Locale('zh'),
      builder: (context, child) {
        return Theme(
          data: Theme.of(context).copyWith(
            dialogBackgroundColor: Colors.white,
          ),
          child: child!,
        );
      },
    );
    if (picked != null && picked != _selectedDate) {
      setState(() {
        _selectedDate = picked;
      });
    }
  }

  List<Map<String, dynamic>> _getFilteredTransactions() {
    DateTime startDate;
    DateTime endDate;

    switch (_selectedPeriod) {
      case '日':
        startDate = DateTime(_selectedDate.year, _selectedDate.month, _selectedDate.day);
        endDate = startDate.add(const Duration(days: 1));
        break;
      case '月':
        startDate = DateTime(_selectedDate.year, _selectedDate.month, 1);
        endDate = DateTime(_selectedDate.year, _selectedDate.month + 1, 1);
        break;
      case '年':
        startDate = DateTime(_selectedDate.year, 1, 1);
        endDate = DateTime(_selectedDate.year + 1, 1, 1);
        break;
      default:
        startDate = DateTime.now();
        endDate = startDate;
    }

    return _transactions.where((tx) {
      final txDate = DateTime.parse(tx['date']);
      return txDate.isAfter(startDate.subtract(const Duration(seconds: 1))) && 
             txDate.isBefore(endDate);
    }).toList();
  }

  Map<String, double> _getCategoryExpenses() {
    final filteredTransactions = _getFilteredTransactions();
    final Map<String, double> categoryExpenses = {};

    for (var tx in filteredTransactions) {
      if (tx['isExpense'] == true) {
        final category = tx['category'];
        categoryExpenses[category] = (categoryExpenses[category] ?? 0) + tx['amount'];
      }
    }

    return categoryExpenses;
  }

  double _getTotalIncome() {
    return _getFilteredTransactions()
        .where((tx) => tx['isExpense'] == false)
        .fold(0.0, (sum, tx) => sum + tx['amount']);
  }

  double _getTotalExpense() {
    return _getFilteredTransactions()
        .where((tx) => tx['isExpense'] == true)
        .fold(0.0, (sum, tx) => sum + tx['amount']);
  }


  String _getDateDisplay() {
    switch (_selectedPeriod) {
      case '日':
        return _dateFormat.format(_selectedDate);
      case '月':
        return _monthFormat.format(_selectedDate);
      case '年':
        return _yearFormat.format(_selectedDate);
      default:
        return '';
    }
  }

  Widget _buildExpenseTrendChart() {
    // 按日期对交易进行分组和计算
    final Map<DateTime, double> dailyExpenses = {};
    final Map<DateTime, double> dailyIncomes = {};
    
    for (var tx in _getFilteredTransactions()) {
      final date = DateTime.parse(tx['date']);
      final dateKey = DateTime(date.year, date.month, date.day);
      if (tx['isExpense'] == true) {
        dailyExpenses[dateKey] = (dailyExpenses[dateKey] ?? 0) + tx['amount'];
      } else {
        dailyIncomes[dateKey] = (dailyIncomes[dateKey] ?? 0) + tx['amount'];
      }
    }

    // 获取所有日期并排序
    final allDates = {...dailyExpenses.keys, ...dailyIncomes.keys}.toList()..sort();
    
    // 如果没有数据，显示提示信息
    if (allDates.isEmpty) {
      return const Center(
        child: Text('暂无数据'),
      );
    }

    // 计算最大值以确定Y轴范围
    final maxExpense = dailyExpenses.isEmpty ? 0 : dailyExpenses.values.reduce(max);
    final maxIncome = dailyIncomes.isEmpty ? 0 : dailyIncomes.values.reduce(max);
    final maxValue = max(maxExpense, maxIncome);

    return AspectRatio(
      aspectRatio: 1.7,
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: LineChart(
          LineChartData(
            gridData: const FlGridData(
              show: true,
              drawHorizontalLine: true,
              drawVerticalLine: true,
            ),
            titlesData: FlTitlesData(
              leftTitles: AxisTitles(
                axisNameWidget: const Text('金额 (￥)'),
                axisNameSize: 24,
                sideTitles: SideTitles(
                  showTitles: true,
                  reservedSize: 60,
                  interval: _calculateInterval(maxValue),
                  getTitlesWidget: (value, meta) {
                    if (value == value.roundToDouble()) {
                      return Text(
                        value == 0 ? '0' : _formatAmount(value),
                        style: const TextStyle(
                          color: Colors.grey,
                          fontSize: 12,
                        ),
                      );
                    }
                    return const Text('');
                  },
                ),
              ),
              bottomTitles: AxisTitles(
                axisNameWidget: const Text('日期'),
                axisNameSize: 24,
                sideTitles: SideTitles(
                  showTitles: true,
                  reservedSize: 30,
                  interval: 1,
                  getTitlesWidget: (value, meta) {
                    if (value < 0 || value >= allDates.length) {
                      return const Text('');
                    }
                    final date = allDates[value.toInt()];
                    String dateText;
                    switch (_selectedPeriod) {
                      case '日':
                        dateText = '${date.day}日';
                        break;
                      case '月':
                        dateText = '${date.month}/${date.day}';
                        break;
                      case '年':
                        dateText = '${date.month}月';
                        break;
                      default:
                        dateText = '${date.month}/${date.day}';
                    }
                    return Text(
                      dateText,
                      style: const TextStyle(
                        color: Colors.grey,
                        fontSize: 12,
                      ),
                    );
                  },
                ),
              ),
              rightTitles: const AxisTitles(
                sideTitles: SideTitles(showTitles: false),
              ),
              topTitles: const AxisTitles(
                sideTitles: SideTitles(showTitles: false),
              ),
            ),
            borderData: FlBorderData(
              show: true,
              border: Border.all(color: Colors.grey.withOpacity(0.2)),
            ),
            minX: -0.5,
            maxX: allDates.length.toDouble() - 0.5,
            minY: 0,
            maxY: maxValue * 1.2,
            lineBarsData: [
              // 支出曲线
              LineChartBarData(
                spots: List.generate(allDates.length, (index) {
                  return FlSpot(
                    index.toDouble(),
                    dailyExpenses[allDates[index]] ?? 0,
                  );
                }),
                isCurved: true,
                color: Colors.red.withOpacity(0.7),
                barWidth: 3,
                isStrokeCapRound: true,
                dotData: const FlDotData(show: true),
                belowBarData: BarAreaData(
                  show: true,
                  color: Colors.red.withOpacity(0.1),
                ),
              ),
              // 收入曲线
              LineChartBarData(
                spots: List.generate(allDates.length, (index) {
                  return FlSpot(
                    index.toDouble(),
                    dailyIncomes[allDates[index]] ?? 0,
                  );
                }),
                isCurved: true,
                color: Colors.green.withOpacity(0.7),
                barWidth: 3,
                isStrokeCapRound: true,
                dotData: const FlDotData(show: true),
                belowBarData: BarAreaData(
                  show: true,
                  color: Colors.green.withOpacity(0.1),
                ),
              ),
            ],
            lineTouchData: LineTouchData(
              touchTooltipData: LineTouchTooltipData(
                tooltipBgColor: Colors.blueAccent,
                getTooltipItems: (List<LineBarSpot> touchedSpots) {
                  return touchedSpots.map((LineBarSpot touchedSpot) {
                    final date = allDates[touchedSpot.x.toInt()];
                    final amount = touchedSpot.y;
                    final isExpense = touchedSpot.barIndex == 0;
                    return LineTooltipItem(
                      '${_dateFormat.format(date)}\n${isExpense ? "支出" : "收入"}: ￥${amount.toStringAsFixed(2)}',
                      TextStyle(
                        color: Colors.white,
                        fontWeight: FontWeight.bold,
                        fontSize: 14,
                      ),
                    );
                  }).toList();
                },
              ),
            ),
          ),
        ),
      ),
    );
  }

  String _formatAmount(num value) {
    if (value >= 10000) {
      return '${(value / 10000).toStringAsFixed(1)}w';
    } else if (value >= 1000) {
      return '${(value / 1000).toStringAsFixed(1)}k';
    }
    return value.toInt().toString();
  }

  double _calculateInterval(num maxValue) {
    if (maxValue <= 0) return 1;
    
    // 计算数量级
    final magnitude = maxValue.toString().split('.')[0].length;
    
    // 根据数量级选择合适的间隔
    if (maxValue >= 10000) {
      return pow(10, magnitude - 2).toDouble(); // 例如：最大值50000，间隔1000
    } else if (maxValue >= 1000) {
      return pow(10, magnitude - 1).toDouble(); // 例如：最大值5000，间隔100
    } else {
      return pow(10, magnitude - 2).toDouble(); // 例如：最大值500，间隔10
    }
  }

  @override
  Widget build(BuildContext context) {
    final categoryExpenses = _getCategoryExpenses();
    final totalIncome = _getTotalIncome();
    final totalExpense = _getTotalExpense();

    return Scaffold(
      appBar: AppBar(
        title: const Text('消费统计'),
        backgroundColor: Theme.of(context).colorScheme.primary,
        foregroundColor: Colors.white,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 时间范围选择
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: ['日', '月', '年'].map((period) {
                        return ChoiceChip(
                          label: Text(period),
                          selected: _selectedPeriod == period,
                          onSelected: (selected) {
                            if (selected) {
                              setState(() {
                                _selectedPeriod = period;
                              });
                            }
                          },
                        );
                      }).toList(),
                    ),
                    const SizedBox(height: 12),
                    TextButton(
                      onPressed: _selectDate,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text(
                            _getDateDisplay(),
                            style: const TextStyle(fontSize: 16),
                          ),
                          const Icon(Icons.arrow_drop_down),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // 收支总览
            Row(
              children: [
                Expanded(
                  child: Card(
                    child: Padding(
                      padding: const EdgeInsets.all(16),
                      child: Column(
                        children: [
                          const Text(
                            '总收入',
                            style: TextStyle(
                              fontSize: 16,
                              color: Colors.grey,
                            ),
                          ),
                          const SizedBox(height: 8),
                          Text(
                            '￥${totalIncome.toStringAsFixed(2)}',
                            style: const TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                              color: Colors.green,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
                const SizedBox(width: 16),
                Expanded(
                  child: Card(
                    child: Padding(
                      padding: const EdgeInsets.all(16),
                      child: Column(
                        children: [
                          const Text(
                            '总支出',
                            style: TextStyle(
                              fontSize: 16,
                              color: Colors.grey,
                            ),
                          ),
                          const SizedBox(height: 8),
                          Text(
                            '￥${totalExpense.toStringAsFixed(2)}',
                            style: const TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                              color: Colors.red,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 16),

            // 消费趋势图
            _buildExpenseTrendChart(),
            const SizedBox(height: 16),

            // 分类统计
            if (categoryExpenses.isNotEmpty)
              Card(
                child: Padding(
                  padding: const EdgeInsets.all(16),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      const Text(
                        '分类统计',
                        style: TextStyle(
                          fontSize: 18,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      const SizedBox(height: 16),
                      ...categoryExpenses.entries.map((entry) {
                        final percentage = (entry.value / totalExpense * 100).toStringAsFixed(1);
                        return Padding(
                          padding: const EdgeInsets.only(bottom: 12),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Row(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                children: [
                                  Text(
                                    entry.key,
                                    style: const TextStyle(
                                      fontSize: 14,
                                      fontWeight: FontWeight.w500,
                                    ),
                                  ),
                                  Text(
                                    '￥${entry.value.toStringAsFixed(2)} ($percentage%)',
                                    style: const TextStyle(
                                      fontSize: 14,
                                      fontWeight: FontWeight.w500,
                                    ),
                                  ),
                                ],
                              ),
                              const SizedBox(height: 4),
                              LinearProgressIndicator(
                                value: entry.value / totalExpense,
                                backgroundColor: Colors.grey[200],
                                valueColor: AlwaysStoppedAnimation<Color>(
                                  Colors.red.withOpacity(0.7),
                                ),
                              ),
                            ],
                          ),
                        );
                      }).toList(),
                    ],
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
} 